﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BoYuanCore.DBServices.Base;
using BoYuanCore.Entities;
using BoYuanCore.Framework.MemoryCache;
using BoYuanCore.Framework.StringUtility;
using BoYuanCore.WebUI.Code;
using BoYuanCore.WebUI.Models;
using FineUICore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;


namespace BoYuanCore.Web.Areas.Admin.Controllers
{
    [Area("Admin")]
    public class SysModuleController : BaseController
    {
        private readonly ILogger<SysModuleController> _logger;
        private readonly IHostingEnvironment _env;
        private readonly ICachingProvider _iCachingProvider;

        //public const bool isHiddenButtonRowExpander = !HaveButtonPermissions;//是否隐藏button权限列表(防止view上.RenderAsRowExpander(BaseController.HaveButtonPermissions).Hidden(!BaseController.HaveButtonPermissions) 显示不一致的but)
        public SysModuleController(ILogger<SysModuleController> logger, IHostingEnvironment env, ICachingProvider iCachingProvider) : base(logger)
        {
            _logger = logger;
            _env = env;
            _iCachingProvider = iCachingProvider;
        }

        #region ListPage
        // GET: Admin/SysModule
        public ActionResult Index()
        {
            //左侧tree绑定
            ViewBag.Tree1DataSource = CreateTree().ToArray();

            

            var btn = UIHelper.Button("Button_delete");
            btn.Hidden(true);

            return View();
        }


        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult ShowGrid(IFormCollection fc)
        {
            int treeid = -1;
            string dataType;
          
            if (fc.Keys.Contains("nodeid") )
            {
                if (int.TryParse(fc["nodeid"], out var tempInt)) treeid = tempInt;
                dataType = fc["dataType"];
            }

            //获取tree节点
            var tree1 = UIHelper.Tree("Tree1");
            var temptag = tree1.Source.AttributeDataTag;

            //todo 缓存
            var query = DB.Select<SysModuleVM>()
                .Where(p=>p.ButtonID=="")//获取文件夹或页面
                .WhereIf(treeid>-1, p=>  
                    p.TreePath.StartsWith(DB.Select<SysModule>().Where(m=>m.ID== treeid)
                        .First(m=>m.TreePath)))
                .OrderBy(p => p.ID);
            //"TreePath LIKE (SELECT s.TreePath+'%' FROM  SysModule s WHERE s.id=@id)",new {id = Tree1.SelectedNodeID});

            var grid1 = UIHelper.Grid("Grid1");
            int pageSize = int.Parse(fc["ddlPageSize"]);

            //获取 文件夹+页面 分页集合
            var list=query.Count(out var recordCount).Page(int.Parse(fc[grid1.Source.ID + "_pageIndex"]) + 1, pageSize).ToList();
            
            var pageIDList = list.Where(p => p.Url != "").Select(p => p.ID).ToList();
            //获取button集合
            var buttonList = DB.Select<SysModule>().Where(p => pageIDList.Contains(p.ParentID) && !string.IsNullOrEmpty(p.ButtonID)).ToList();

            if (buttonList.Count > 0 && HaveButtonPermissions)
            {
                foreach (var pg in list)
                {
                    if (!string.IsNullOrEmpty(pg.Url)) //为页面
                        pg.ShowButtonInfo = GetButtonHtml(buttonList, pg.ID);
                }
            }

            grid1.DataSource(list, fc[grid1.Source.ID + "_fields[]"].ToString().Split(','));
            grid1.RecordCount((int)recordCount);
            grid1.PageSize(pageSize);

            return UIHelper.Result();
        }

        /// <summary>
        /// 显示button html
        /// </summary>
        /// <param name="list"></param>
        /// <param name="pid"></param>
        /// <returns></returns>
        private string GetButtonHtml(List<SysModule> list,int pid)
        {
/* //所需的css，参考：https://pro.fineui.com/#/grid/grid_rowexpander_htmlgrid.aspx https://core.fineui.com/#/Grid/RowExpanderHtmlGrid
 <style>
     .mytable {border-width: 1px;border-style: solid;border-collapse: separate;border-spacing: 0;border-bottom-width: 0;border-right-width: 0;}
     .mytable th,.mytable td {padding: 5px;text-align: left;border-bottom-width: 1px;border-bottom-style: solid;border-right-width: 1px;border-right-style: solid;}
 </style>
*/
            var buttonList = list.Where(p => p.ParentID == pid ).ToList();
            StringBuilder newLine = new StringBuilder("");
            
            if (buttonList.Count > 0)
            {
                newLine.Append("<table class=\"mytable f-widget-header\">");
                //head
                newLine.Append("<tr>");
                newLine.Append("<th class=\"f-widget-header\" style=\"width:120px\">按钮ID</th>");
                newLine.Append("<th class=\"f-widget-header\" style=\"width:200px\">按钮名称</th>");
                newLine.Append("<th class=\"f-widget-header\" style=\"width:200px\">对应action</th>");
                newLine.Append("<th class=\"f-widget-header\" style=\"width:50px\">状态</th>");
                newLine.Append("<th class=\"f-widget-header\" style=\"width:50px\">编辑</th>");
                newLine.Append("<th class=\"f-widget-header\" style=\"width:50px\">删除</th>");
                newLine.Append("</tr>");
                foreach (var btn in buttonList)
                {
                    newLine.Append("<tr>");
                    newLine.AppendFormat("<th class=\"f-widget-content\" >{0}</th>", btn.ButtonID);
                    newLine.AppendFormat("<th class=\"f-widget-content\" >{0}</th>", btn.ButtonText);
                    newLine.AppendFormat("<th class=\"f-widget-content\" >{0}</th>", btn.Url);
                    newLine.AppendFormat("<th class=\"f-widget-content\" >{0}</th>", btn.IsHidden?"<font color='red'>隐藏</font>":"正常");
                    newLine.AppendFormat("<th class=\"f-widget-content\" >{0}</th>", HTMLTag.GetHtmlAJs("EditBtn("+btn.ID+")", HTMLTag.GetHtmlImg("/res/icon/pencil.png")));
                    newLine.AppendFormat("<th class=\"f-widget-content\" >{0}</th>", HTMLTag.GetHtmlAJs("DeleteBtn(" + btn.ID + ")", HTMLTag.GetHtmlImg("/res/icon/delete.png")));
                    newLine.Append("</tr>");
                }
                newLine.Append("</table>");
            }
            
            return newLine.ToString();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult BtnDelete_Click(string ids)
        {
            if (string.IsNullOrWhiteSpace(ids))
            {
                NotifyQuestion("请选择要删除的选中行！");
            }
            else
            {
                var idList = Array.ConvertAll(ids.Substring(1).Split(','), long.Parse);
                if (idList.Length == 0)
                {
                    NotifyQuestion("请选择要删除的选中行！");
                }
                else
                {
                    DB.Delete<SysModule>().Where(p => idList.Contains(p.ID)).ExecuteAffrows(); 
                    //更新叶节点
                    DBServices.SysModule.UpdateTreeLeaf();
                    DBServices.SysModule.RemoveSysModuleListCache(_iCachingProvider);
                    AlertSuccess("删除成功！", false, "GridAndTree();");
                }
            }
            return UIHelper.Result();
        }
        #endregion

        #region AddPage

        public ActionResult Add()
        {
            //获取url
            ViewBag.ddl_url_DataSource = CommonClass.GetMvcUrl(_env);

            if (int.TryParse(Request.Query["id"], out int id))//编辑页面初始化
            {
                SysModule mo = DB.Select<SysModule>().WhereDynamic(id).First();
                ViewBag.haveUpdate = 1;

                //左侧tree绑定
                ViewBag.Tree1DataSource = CreateTree().ToArray();
                ViewBag.pid = mo.ParentID;
                ViewBag.treePath = mo.TreePath;

                ViewBag.url = mo.Url;
                return View(mo);
            }
            else //添加
            {
                int pid =-1;
                if (int.TryParse(Request.Query["pid"], out int pidResult)) pid = pidResult;

                if (pid > 0)
                {
                    var mo = DB.Select<SysModule>().WhereDynamic(pid).First(); 
                    ViewBag.pid = mo.ID;
                    ViewBag.treePath = mo.TreePath;
                }
                else
                {
                    ViewBag.pid =0;
                    ViewBag.treePath = string.Empty;
                }

                //左侧tree绑定
                ViewBag.Tree1DataSource = CreateTree().ToArray();
                return View();//添加页面
            }
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult BtnSave_OnClick(IFormCollection fc)
        {
            bool isEdit = int.TryParse(fc["f_ID"], out int ID);

            SysModule mo = isEdit? DB.Select<Entities.SysModule>().WhereDynamic(ID).First(): new SysModule();

            mo.IsHidden = Convert.ToBoolean(fc["f_IsHidden"]);
            mo.IsLeaf = Convert.ToBoolean(fc["f_IsLeaf"]);
            mo.PageTitle = fc["f_PageTitle"];
            if (int.TryParse(fc["f_ParentID"], out var ParentIDTempResult)) mo.ParentID = ParentIDTempResult;
            mo.Remark = fc["f_Remark"];
            if (int.TryParse(fc["f_Sort"], out var SortTempResult)) mo.Sort = SortTempResult;
            mo.TreePath = fc["f_TreePath"];
            mo.Url = fc["f_Url_text"].ToString().ToLower();

            if (isEdit && mo.ParentID==mo.ID)//编辑状态下，父节点不能为自己
            {
                AlertError("父节点不能为自己",false);
                return UIHelper.Result();
            }

            if (!isEdit)//添加
            {
                mo.ID = DBServices.SysModule.GetID();
                mo.FontIcon = string.Empty;
                mo.Icon = string.Empty;

                int tempid = (int) DB.Insert(mo).ExecuteAffrows();
                if (tempid>0)
                {
                    //设置绝对路径
                    DBServices.SysModule.UpdateTreePath(mo.ID);
                    //更新叶节点
                    DBServices.SysModule.UpdateTreeLeaf();
                    DBServices.SysModule.RemoveSysModuleListCache(_iCachingProvider);
                    AlertInfor("添加成功");
                }
                else
                {
                    NotifyError("添加失败");
                }
            }
            else//修改
            {
                mo.ID = ID;

                if (mo.ID == mo.ParentID)
                {
                    NotifyError("修改失败,父节点不能为自己");
                    return UIHelper.Result();
                }

                bool result = DBServices.SysModule.UpdateModuleByEntity(mo, _iCachingProvider);

                if (result)
                {
                    AlertInfor("修改成功");
                }
                else
                {
                    NotifyError("修改失败");
                }
            }
            return UIHelper.Result();
        }
        #endregion

        #region AddButton

        public ActionResult AddButton()
        {
            //获取url
            ViewBag.ddl_url_DataSource = CommonClass.GetMvcUrl(_env);

            if (int.TryParse(Request.Query["id"], out int id))//编辑页面初始化
            {
                SysModule mo = DB.Select<SysModule>().WhereDynamic(id).First();
                ViewBag.haveUpdate = 1;

                //左侧tree绑定
                ViewBag.Tree1DataSource = CreateTree().ToArray();
                ViewBag.pid = mo.ParentID;
                ViewBag.treePath = mo.TreePath;
                return View(mo);
            }
            else //添加
            {
                int pid = -1;
                if (int.TryParse(Request.Query["pid"], out int pidResult)) pid = pidResult;

                if (pid > 0)
                {
                    var mo = DB.Select<SysModule>().WhereDynamic(pid).First();
                    ViewBag.pid = mo.ID;
                    ViewBag.treePath = mo.TreePath;
                }
                else
                {
                    ViewBag.pid = -1;
                    ViewBag.treePath = string.Empty;
                }

                //左侧tree绑定
                ViewBag.Tree1DataSource = CreateTree().ToArray();
                return View();//添加页面
            }
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult BtnSaveButton_OnClick(IFormCollection fc)
        {
            bool isEdit = int.TryParse(fc["f_ID"], out int ID);

            SysModule mo = isEdit ? DB.Select<Entities.SysModule>().WhereDynamic(ID).First() : new SysModule();

            mo.IsHidden = Convert.ToBoolean(fc["f_IsHidden"]);
            mo.IsLeaf = Convert.ToBoolean(fc["f_IsLeaf"]);
            mo.PageTitle = fc["f_PageTitle"];
            if (int.TryParse(fc["f_ParentID"], out var ParentIDTempResult)) mo.ParentID = ParentIDTempResult;
            mo.Remark = fc["f_Remark"];
            if (int.TryParse(fc["f_Sort"], out var SortTempResult)) mo.Sort = SortTempResult;
            mo.TreePath = fc["f_TreePath"];
            mo.Url = fc["f_url"].ToString().ToLower();
            mo.ButtonID = fc["f_ButtonID"];
            mo.ButtonText = fc["f_ButtonText"];

            if (isEdit && mo.ParentID == mo.ID)//编辑状态下，父节点不能为自己
            {
                AlertError("父节点不能为自己", false);
                return UIHelper.Result();
            }

            if (!isEdit)//添加
            {
                mo.ID = DBServices.SysModule.GetID();
                mo.FontIcon = string.Empty;
                mo.Icon = string.Empty;

                int tempid = (int)DB.Insert(mo).ExecuteAffrows();
                if (tempid > 0)
                {
                    //设置绝对路径
                    DBServices.SysModule.UpdateTreePath(tempid);
                    DBServices.SysModule.RemoveSysModuleListCache(_iCachingProvider);
                    AlertInfor("添加成功");
                }
                else
                {
                    NotifyError("添加失败");
                }
            }
            else//修改
            {
                mo.ID = ID;

                if (mo.ID == mo.ParentID)
                {
                    NotifyError("修改失败,父节点不能为自己");
                    return UIHelper.Result();
                }

                bool result = DBServices.SysModule.UpdateModuleByEntity(mo, _iCachingProvider);

                if (result)
                {
                    AlertInfor("修改成功");
                }
                else
                {
                    NotifyError("修改失败");
                }
            }
            return UIHelper.Result();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteBtnData(int id)
        {
            bool result = DB.Delete<Entities.SysModule>().Where(p => p.ID == id && !string.IsNullOrEmpty(p.ButtonID))
                .ExecuteAffrows() > 0;
            if (result)
            {
                DBServices.SysModule.RemoveSysModuleListCache(_iCachingProvider);
                AlertSuccess("删除成功！", false, "onGridBind()");
            }
            else
            {
                AlertError("删除失败",false);
            }

            return UIHelper.Result();
        }

        #endregion


        #region tree 相关

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult BindTree(IFormCollection fc)
        {
            //重新绑定tree
            UIHelper.Tree("Tree1").LoadData(CreateTree());
            UIHelper.Tree("Tree1").SelectedNodeID(fc["nodeid"].ToString());
            return UIHelper.Result();
        }

        /// <summary>
        /// 绑定tree
        /// </summary>
        /// <returns></returns>
        public IList<TreeNode> CreateTree()
        {
            var moduleList = DBServices.SysModule.GetSysModuleListByCache(_iCachingProvider, HaveButtonPermissions);
            IList<TreeNode> nodes = new List<TreeNode>();
            nodes.Add(new TreeNode() { NodeID = "-1", Text = "顶级", Expanded = true ,Attributes = JObject.Parse("{'dataType':'1'}") });
         
            var list = moduleList.Where(p => p.ParentID == 0 && string.IsNullOrEmpty(p.ButtonID)).OrderBy(p => p.Sort).ToList();

            TreeNode node;
            foreach (var module in list)
            {
                node = new TreeNode();

                node.NodeID = module.ID.ToString();
                node.Text = module.PageTitle + (module.Remark.Length > 0 ? "(" + module.Remark + ")" : string.Empty) +
                            (module.IsHidden ? "<font color='red'>不显示</font>" : string.Empty);

                if (!string.IsNullOrEmpty(module.Icon)) node.IconUrl = "/" + module.Icon;
                if (!string.IsNullOrEmpty(module.FontIcon)) node.IconFont = (IconFont)Enum.Parse(typeof(IconFont), module.FontIcon);

                node.Expanded = true;//默认节点都为展开
                
                //1 文件夹 2 页面 3 button
                node.Attributes= JObject.Parse("{'dataType':'"+(string.IsNullOrEmpty(module.Url)?"1":"2")+"'}");
                //node.Checked = module.ID.ToString() == checkedValue;//设置选中效果并不好用，改成js方式或者用 UIHelper.Tree("Tree1").SelectedNodeID( "hefei"); 

                CreateTreeNodes(moduleList, node);
                nodes.Add(node);
            }

            return nodes;
        }
        public static void CreateTreeNodes(List<SysModule> moduleList, TreeNode parentNode)
        {
            var list = moduleList.Where(p => p.ParentID.ToString() == parentNode.NodeID && string.IsNullOrEmpty(p.ButtonID)).OrderBy(p => p.Sort).ToList();

            if (list == null || list.Count == 0) return;

            TreeNode node;
            foreach (var module in list)
            {
                node = new TreeNode();

                node.NodeID = module.ID.ToString();
                node.Text = module.PageTitle + (module.Remark.Length > 0 ? "(" + module.Remark + ")" : string.Empty) +
                            (module.IsHidden ? "<font color='red'>不显示</font>" : string.Empty);

                if (!string.IsNullOrEmpty(module.Icon)) node.IconUrl = "/" + module.Icon;
                if (!string.IsNullOrEmpty(module.FontIcon)) node.IconFont = (IconFont)Enum.Parse(typeof(IconFont), module.FontIcon);

                node.Expanded = true;//默认节点都为展开

                //1 文件夹 2 页面 3 button
                node.Attributes = JObject.Parse("{'dataType':'" + (string.IsNullOrEmpty(module.Url) ? "1" : "2") + "'}");

                //node.Checked = module.ID.ToString() == checkedValue;//设置选中效果并不好用，改成js方式

                CreateTreeNodes(moduleList, node);
                parentNode.Nodes.Add(node);
            }
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Tree1_OnNodeCheck(string nodeid)
        {
            var parentID = UIHelper.Label("f_ParentID");
            var treePath = UIHelper.Label("f_TreePath");
            if (!string.IsNullOrEmpty(nodeid))
            {
                Entities.SysModule mo = FreeSqlHelper.GetModel<Entities.SysModule>(nodeid);

                if (mo != null)
                {
                    parentID.Text(mo.ID.ToString());
                    treePath.Text(mo.TreePath);
                }
                else
                {
                    parentID.Text("0");
                    treePath.Text(string.Empty);
                }
            }
            else
            {
                parentID.Text("0");
                treePath.Text(string.Empty);
            }

            return UIHelper.Result();
        }

        #endregion

        #region Icons 图标
        // GET: Config/Icons
        public IActionResult Icons(string id)
        {
            long.Parse(id);
            ViewBag.id = id;
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult UpdateIcon(string id,string src)
        {
            if (string.IsNullOrEmpty(src)) {src = string.Empty;}
            else
            {
                src = src.Substring(1);//去掉开头的 /
            }
            //GetInstance().Update<T>().Set(columns).Where(expressionWhere).ExecuteAffrows();
            int temp =DB.Update<SysModule>(id).Set(p => new SysModule() {Icon = src,FontIcon = ""}).ExecuteAffrows();
            if (temp > 0)
            {
                DBServices.SysModule.RemoveSysModuleListCache(_iCachingProvider);
                AlertSuccess("设置成功");
            }
            else
            {
                NotifyError("设置失败");
            }
            return UIHelper.Result();
        }
        #endregion   

        #region IconFonts 图标字体
        public IActionResult IconFonts(string id)     
        {
            long.Parse(id);
            ViewBag.id = id;
            return View();
        }

        public IActionResult IconFontsFa(string id)
        {
            long.Parse(id);
            ViewBag.id = id;
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public IActionResult UpdateIconFonts(string id,string font)
        {
            var temp = DBServices.SysModule.UpdateFontIcon(font, int.Parse(id));
            if (temp)
            {
                DBServices.SysModule.RemoveSysModuleListCache(_iCachingProvider);
                AlertSuccess("设置成功");
            }
            else
            {
                NotifyError("设置失败");
            }
            return UIHelper.Result();
        }
        #endregion

    }
}

